package com.chess.touch.demo;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class TextViewAnnotation extends RelativeLayout implements OnTouchListener {

	private static final float DEFAULT_SIZE = 20.0f;
	protected Context context;
	protected TextView textView;
	protected String textContent;

	protected View topLeftView = null;
	protected View topRightView = null;
	protected View bottomLeftView = null;
	protected View bottomRightView = null;
	private int resizeAreaBackgroundColor = 0;

	private float startX;
	private float startY;
	int lastX, lastY;
	private int screenWidth;
	private int screenHeight;
	private int annotationResizeLength;
	private int annotationMinHeight;

	private int annotationViewWidthOriginal = 0;
	private int annotationViewHeightOriginal = 0;
	private ViewGroup annotaionViewOriginal = null;
	private int annotaionViewOriginalLeft = 0;
	private int annotaionViewOriginalTop = 0;

	private ViewGroup annotationViewToBeUpdated;
	private int titleBarHeight = -1;
	private int statusBarHeight = -1;
	private boolean annotationResizeAreaVisible;

	public TextViewAnnotation(final Context context, final AttributeSet attrSet, String content) {
		super(context, attrSet);
		this.textContent = content;
		this.context = context;
		instantiate();
	}

	public TextViewAnnotation(final Context context, String content) {
		super(context);
		this.textContent = content;
		this.context = context;
		instantiate();
	}

	public TextViewAnnotation(final Context context, final AttributeSet attrSet) {
		super(context, attrSet);
		this.context = context;
		instantiate();
	}

	public void initScreenWidthAndHeight() {
		DisplayMetrics dm = new DisplayMetrics();
		((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(dm);
		screenWidth = dm.widthPixels;
		screenHeight = dm.heightPixels;

	}

	protected void instantiate() {
		resizeAreaBackgroundColor = getResources().getColor(R.color.red);
		initScreenWidthAndHeight();
		this.setGravity(Gravity.CENTER);
		initAnnotationResizeViews();
		initTextView();
		this.setBackgroundColor(getResources().getColor(R.color.green_signature_background));
		this.getBackground().setAlpha(Constants.SIGNATURE_ALPHA);
		setAnnotationResizeViewInivisble();
		setOnTouchListener();

	}

	private void setAnnotationResizeViewInivisble() {
		topLeftView.setVisibility(View.INVISIBLE);
		topRightView.setVisibility(View.INVISIBLE);
		bottomLeftView.setVisibility(View.INVISIBLE);
		bottomRightView.setVisibility(View.INVISIBLE);
	}

	private void setAnnotationResizeViewVisble() {
		topLeftView.setVisibility(View.VISIBLE);
		topRightView.setVisibility(View.VISIBLE);
		bottomLeftView.setVisibility(View.VISIBLE);
		bottomRightView.setVisibility(View.VISIBLE);
	}

	private void setOnTouchListener() {
		this.setOnTouchListener(this);
		topLeftView.setOnTouchListener(this);
		topRightView.setOnTouchListener(this);
		bottomLeftView.setOnTouchListener(this);
		bottomRightView.setOnTouchListener(this);

	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if (v == this) {
			return handleMoveView(v, event);
		} else {
			return handleResizeView(v, event);
		}
	}

	private boolean handleResizeView(View v, MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			initAnnotationParameters(v, event);
			break;
		case MotionEvent.ACTION_MOVE:
			updateAnnotationSize(v, event);
			break;
		case MotionEvent.ACTION_UP:
			retoreAnnotationView(v, event);
			break;
		default:
			break;
		}
		return true;
	}

	public void setAnnotationResizeAreaBackgroundColor(int backgroundColor) {
		topLeftView.setBackgroundColor(backgroundColor);
		topRightView.setBackgroundColor(backgroundColor);
		bottomLeftView.setBackgroundColor(backgroundColor);
		bottomRightView.setBackgroundColor(backgroundColor);
	}

	private void initAnnotationResizeViews() {
		annotationResizeLength = (int)context.getResources().getDimension(R.dimen.annotation_resize_area);
		annotationMinHeight = annotationResizeLength * 3;

		LayoutParams paramsTopLeft = new LayoutParams(annotationResizeLength, annotationResizeLength);
		paramsTopLeft.addRule(ALIGN_PARENT_LEFT);
		paramsTopLeft.addRule(ALIGN_PARENT_TOP);
		topLeftView = new View(context);
		topLeftView.setBackgroundColor(resizeAreaBackgroundColor);
		addView(topLeftView, paramsTopLeft);

		LayoutParams paramsTopRight = new LayoutParams(annotationResizeLength, annotationResizeLength);
		paramsTopRight.addRule(ALIGN_PARENT_RIGHT);
		paramsTopRight.addRule(ALIGN_PARENT_TOP);
		topRightView = new View(context);
		topRightView.setBackgroundColor(resizeAreaBackgroundColor);
		addView(topRightView, paramsTopRight);

		LayoutParams paramsBottomLeft = new LayoutParams(annotationResizeLength, annotationResizeLength);
		paramsBottomLeft.addRule(ALIGN_PARENT_LEFT);
		paramsBottomLeft.addRule(ALIGN_PARENT_BOTTOM);
		bottomLeftView = new View(context);
		bottomLeftView.setBackgroundColor(resizeAreaBackgroundColor);
		addView(bottomLeftView, paramsBottomLeft);

		LayoutParams paramsBottomRight = new LayoutParams(annotationResizeLength, annotationResizeLength);
		paramsBottomRight.addRule(ALIGN_PARENT_RIGHT);
		paramsBottomRight.addRule(ALIGN_PARENT_BOTTOM);
		bottomRightView = new View(context);
		bottomRightView.setBackgroundColor(resizeAreaBackgroundColor);
		addView(bottomRightView, paramsBottomRight);

	}

	private void initTextView() {
		textView = new TextView(context);
		textView.setText(textContent);
		textView.setTextSize(DEFAULT_SIZE);
		LayoutParams paramsTextView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		paramsTextView.addRule(LEFT_OF, topRightView.getId());
		paramsTextView.addRule(RIGHT_OF, topLeftView.getId());
		paramsTextView.addRule(ABOVE, bottomLeftView.getId());
		paramsTextView.addRule(BELOW, topLeftView.getId());
		paramsTextView.addRule(CENTER_IN_PARENT);
		addView(textView, paramsTextView);
	}

	private void retoreAnnotationView(View v, MotionEvent event) {
		annotationViewToBeUpdated.setBackgroundColor(getResources().getColor(R.color.green_signature_background));
		annotationViewToBeUpdated.getBackground().setAlpha(Constants.SIGNATURE_ALPHA);
	}

	private void initAnnotationParameters(View v, MotionEvent event) {

		if (v == this) {
			annotaionViewOriginal = (ViewGroup)v;
		} else {
			annotaionViewOriginal = (ViewGroup)v.getParent();
		}
		annotaionViewOriginal.setBackgroundColor(getResources().getColor(R.color.green_signature_background_on_drag));
		annotaionViewOriginal.getBackground().setAlpha(Constants.SIGNATURE_ALPHA_ON_DRAG);
		annotationViewWidthOriginal = annotaionViewOriginal.getWidth();
		annotationViewHeightOriginal = annotaionViewOriginal.getHeight();
		annotaionViewOriginalLeft = annotaionViewOriginal.getLeft();
		annotaionViewOriginalTop = annotaionViewOriginal.getTop();
		startX = (int)event.getRawX();
		startY = (int)event.getRawY();
	}

	private void updateAnnotationSize(View view, MotionEvent event) {
		annotationViewToBeUpdated = (ViewGroup)view.getParent();
		ViewGroup topView = (ViewGroup)annotationViewToBeUpdated.getParent();
		topView.updateViewLayout(annotationViewToBeUpdated, getAnnotationViewParamToBeUpdated(view, event));

	}

	private LayoutParams getAnnotationViewParamToBeUpdated(View v, MotionEvent event) {

		int width = 0;
		int height = 0;
		int left = 0;
		int top = 0;

		float currentX = event.getRawX();
		float currentY = event.getRawY();
		float dx = currentX - startX;
		float dy = currentY - startY;

		if (v == topLeftView) {
			width = Math.max(Math.abs(annotationViewWidthOriginal - (int)(dx + 0.5f)), annotationMinHeight);
			height = Math.max(Math.abs(annotationViewHeightOriginal - (int)(dy + 0.5f)), annotationMinHeight);
			left = annotaionViewOriginal.getRight() - width;
			top = annotaionViewOriginal.getBottom() - height;
		} else if (v == topRightView) {
			width = Math.max(Math.abs(annotationViewWidthOriginal + (int)(dx + 0.5f)), annotationMinHeight);
			height = Math.max(Math.abs(annotationViewHeightOriginal - (int)(dy + 0.5f)), annotationMinHeight);
			left = annotaionViewOriginal.getLeft();
			top = annotaionViewOriginal.getBottom() - height;
		} else if (v == bottomLeftView) {
			width = Math.max(Math.abs(annotationViewWidthOriginal - (int)(dx + 0.5f)), annotationMinHeight);
			height = Math.max(Math.abs(annotationViewHeightOriginal + (int)(dy + 0.5f)), annotationMinHeight);
			left = annotaionViewOriginal.getRight() - width;
			top = annotaionViewOriginal.getTop();
		} else if (v == bottomRightView) {
			width = Math.max(Math.abs(annotationViewWidthOriginal + (int)(dx + 0.5f)), annotationMinHeight);
			height = Math.max(Math.abs(annotationViewHeightOriginal + (int)(dy + 0.5f)), annotationMinHeight);
			left = annotaionViewOriginal.getLeft();
			top = annotaionViewOriginal.getTop();
		}
		LayoutParams params = new LayoutParams(width, height);
		params.leftMargin = left;
		params.topMargin = top;
		return params;
	}

	// private void updateDragViewInParent(int left, int top) {
	// LayoutParams params = new LayoutParams(currentClickedView.getWidth(), currentClickedView.getHeight());
	// params.leftMargin = left;
	// params.topMargin = top;
	// ViewGroup parent = (ViewGroup)currentClickedView.getParent();
	// parent.updateViewLayout(currentClickedView, params);
	//
	// }

	private boolean handleMoveView(View v, MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			initAnnotationParameters(v, event);
			break;
		case MotionEvent.ACTION_MOVE:
			updateAnnotationPosition(v, event);
			break;
		case MotionEvent.ACTION_UP:
			detectAnnotationAction(v, event);

			break;
		default:
			break;
		}
		return true;
	}

	private void detectAnnotationAction(View v, MotionEvent event) {
		float currentX = event.getRawX();
		float currentY = event.getRawY();
		if (Math.abs(currentX - startX) < 8 && Math.abs(currentY - startY) < 8) {
			if (annotationResizeAreaVisible) {
				setAnnotationResizeViewInivisble();
				showAnnotationMenu();
			} else {
				setAnnotationResizeViewVisble();
			}
			annotationResizeAreaVisible = !annotationResizeAreaVisible;

		} else {
			retoreAnnotationView(v, event);
		}
	}

	private void showAnnotationMenu() {
		AlertDialog.Builder builder = new AlertDialog.Builder(context).setCancelable(true).setItems(
				R.array.signature_text_edit_menu, menuListener);
		AlertDialog dialog = builder.create();
		dialog.show();

	}

	private DialogInterface.OnClickListener menuListener = new DialogInterface.OnClickListener() {

		@Override
		public void onClick(DialogInterface dialog, int which) {
			switch (which) {
			case 0:
				doEdit();
				break;
			case 1:
				doResize();
				break;
			case 2:
				doDelete();
				break;
			case 3:
				break;
			}

		}

	};

	private void doResize() {

		//
		// signatureSlidingDrawer.open();
		// signaturesGallery.setVisibility(View.INVISIBLE);
		// seekbar.setVisibility(View.VISIBLE);

	}

	private void doEdit() {
		//
		// customContent.setVisibility(View.VISIBLE);
		// customContent.setText(((TextView)currentClickedView).getText());
		// topLayout.bringChildToFront(customContent);
		// topLayout.invalidate();
	}

	private void doDelete() {

		ViewGroup parent = (ViewGroup)annotaionViewOriginal.getParent();
		parent.removeView(annotaionViewOriginal);
		// signatureListView.remove(currentClickedView);
		// signatureMenuLayout.setVisibility(View.INVISIBLE);

	}

	private void updateAnnotationPosition(View view, MotionEvent event) {

		annotationViewToBeUpdated = (ViewGroup)view;
		ViewGroup topView = (ViewGroup)annotationViewToBeUpdated.getParent();
		topView.updateViewLayout(annotationViewToBeUpdated, getAnnotationViewNewParam(view, event));

	}

	private LayoutParams getAnnotationViewNewParam(View view, MotionEvent event) {
		float currentX = event.getRawX();
		float currentY = event.getRawY();
		float dx = currentX - startX;
		float dy = currentY - startY;
		int left = (int)(annotaionViewOriginalLeft + dx);
		int top = (int)(annotaionViewOriginalTop + dy);
		int right = left + annotationViewWidthOriginal;
		int bottom = top + annotationViewHeightOriginal;

		if (left < 0) {
			left = 0;
		}

		if (right > screenWidth) {
			// right = screenWidth;
			left = screenWidth - annotationViewWidthOriginal;
		}

		if (top < 0) {
			top = 0;
			// bottom = top +annotationViewHeightOriginal;
		}
		if (bottom > screenHeight - getStatusBarHeight() - getTitleBarHeight()) {
			bottom = screenHeight - getStatusBarHeight() - getTitleBarHeight();
			top = bottom - annotationViewHeightOriginal;
		}
		LayoutParams params = new LayoutParams(annotationViewWidthOriginal, annotationViewHeightOriginal);
		params.leftMargin = left;
		params.topMargin = top;
		return params;
	}

	private int getStatusBarHeight() {

		if (statusBarHeight > 0) {
			return statusBarHeight;
		}
		Rect rectgle = new Rect();
		Window window = ((Activity)context).getWindow();
		window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
		statusBarHeight = rectgle.top;
		return statusBarHeight;

	}

	public int getTitleBarHeight() {

		if (titleBarHeight > 0) {
			return titleBarHeight;
		}
		Rect rect = new Rect();
		Window win = ((Activity)context).getWindow();
		win.getDecorView().getWindowVisibleDisplayFrame(rect);
		int statusBarHeight = rect.top;
		int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();
		titleBarHeight = contentViewTop - statusBarHeight;
		return titleBarHeight;
	}

}